package org.jet.emall.prod.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import org.jet.emall.common.exception.CustomServiceException;
import org.jet.emall.common.restful.result.CommonPage;
import org.jet.emall.prod.dto.*;
import org.jet.emall.prod.po.ProdBrand;
import org.jet.emall.prod.po.ProdCate;
import org.jet.emall.prod.po.ProdCateBrand;
import org.jet.emall.prod.po.ProdSpu;
import org.jet.emall.prod.service.mp.IProdBrandService;
import org.jet.emall.prod.service.mp.IProdCateBrandService;
import org.jet.emall.prod.service.mp.IProdCateService;
import org.jet.emall.prod.service.mp.IProdSpuService;
import org.jet.emall.prod.transfer.BrandDtoTransfer;
import org.jet.emall.prod.transfer.CategoryDtoTransfer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;

/**
 * @author xiaozai
 * @version 1.0
 * @date 2020-04-16 13:51
 */
@Service
public class CustomBrandServiceImpl implements CustomBrandService {
    @Autowired
    private IProdBrandService prodBrandService;
    @Autowired
    private IProdCateBrandService prodCateBrandService;
    @Autowired
    private IProdCateService prodCateService;
    @Autowired
    private IProdSpuService prodSpuService;
    @Override
    public CommonPage<BrandDTO> page(String query, Integer pageNum, Integer pageSize) {
        IPage<ProdBrand> page = prodBrandService.page(new Page<ProdBrand>().setCurrent(pageNum).setSize(pageSize),
                                                      new QueryWrapper<ProdBrand>().like(StringUtils.isNotBlank(query),"name",query));
        return new CommonPage<BrandDTO>().setTotalPage(page.getPages()).setTotal(page.getTotal()).setPageSize(page.getSize()).setPageNum(page.getCurrent()).setList(BrandDtoTransfer.INSTANCE.toDtoList(page.getRecords()));
    }

    @Override
    public List<BrandDTO> query(String query) {
        return BrandDtoTransfer.INSTANCE.toDtoList(prodBrandService.list(new QueryWrapper<ProdBrand>().like(StringUtils.isNotBlank(query),"name",query)));
    }

    @Override
    public List<BrandDTO> list(Integer cate3Id) {
        List<ProdCateBrand> cateBrands = prodCateBrandService.list(new QueryWrapper<ProdCateBrand>().eq("cate_id", cate3Id));
        if(cateBrands==null||cateBrands.isEmpty()){
            throw new CustomServiceException("该分类下没有品牌");
        }
        List<Integer> ids = cateBrands.stream().mapToInt(v -> v.getBrandId()).collect(ArrayList<Integer>::new, List::add, List::addAll);
        return BrandDtoTransfer.INSTANCE.toDtoList(prodBrandService.listByIds(ids));

    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void update(Integer id, Byte status) {
        prodBrandService.updateById(new ProdBrand().setId(id).setStatus(status));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void saveBrand(NewBrandDTO dto) {
        ProdBrand prodBrand = BrandDtoTransfer.INSTANCE.toPo(dto);
        prodBrandService.save(prodBrand);
        List<ProdCateBrand> list = new LinkedList<>();
        dto.getCates().forEach(id->{
            list.add(new ProdCateBrand().setCateId(id).setBrandId(prodBrand.getId()));
        });
        prodCateBrandService.saveBatch(list);
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteBrands(List<Integer> ids) {
        //如果品牌下还有商品则不能删除
        int count = prodSpuService.count(new QueryWrapper<ProdSpu>().in("brand_id", ids));
        if(count>0){
            throw new CustomServiceException("该品牌还有商品在售，禁止删除");
        }
        prodCateBrandService.remove(new QueryWrapper<ProdCateBrand>().in("brand_id",ids));
        prodBrandService.removeByIds(ids);
    }

    @Override
    public void updateBrand(UpdateBrandDTO brandDTO) {
        ProdBrand prodBrand = BrandDtoTransfer.INSTANCE.toPo(brandDTO);
        prodBrandService.updateById(prodBrand);
        List<Integer> cateIdList = prodCateBrandService.list(new QueryWrapper<ProdCateBrand>().eq("brand_id", prodBrand.getId()))
                .stream().mapToInt(v -> v.getCateId()).collect(ArrayList<Integer>::new, List::add, List::addAll);
        List<Integer> idsInTable = new LinkedList<>(cateIdList);
        idsInTable.removeAll(brandDTO.getCates());
        if(!idsInTable.isEmpty()) {
            int count = prodSpuService.count(new QueryWrapper<ProdSpu>().eq("brand_id", brandDTO.getId())
                    .in("cate_id", idsInTable));
            if(count>0){
                throw new CustomServiceException("该品牌要删除的分类下还有商品在售，禁止删除");
            }
            prodCateBrandService.remove(new QueryWrapper<ProdCateBrand>().in("cate_id",idsInTable));
        }
        brandDTO.getCates().removeAll(cateIdList);
        List<ProdCateBrand> list = new LinkedList<>();
        if(!brandDTO.getCates().isEmpty()){
            brandDTO.getCates().forEach(id->{
                list.add(new ProdCateBrand().setBrandId(prodBrand.getId()).setCateId(id));
            });
            prodCateBrandService.saveBatch(list);
        }
    }

    @Override
    public BrandDetailsDTO getBrandDetails(Integer id) {
        ProdBrand prodBrand = prodBrandService.getById(id);
        BrandDetailsDTO dto = BrandDtoTransfer.INSTANCE.toDto(prodBrand);
        ArrayList<Integer> cateIdList = prodCateBrandService.list(new QueryWrapper<ProdCateBrand>().eq("brand_id", id))
                .stream().mapToInt(v -> v.getCateId()).collect(ArrayList<Integer>::new, List::add, List::addAll);
        List<ProdCate> prodCates = prodCateService.listByIds(cateIdList);
        List<ProdCateDTO> dtoList = CategoryDtoTransfer.INSTANCE.toProdCateDtoList(prodCates);
        dto.setCates(dtoList);
        return dto;
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void deleteCate(Integer brandId, Integer cateId) {
        int count = prodSpuService.count(new QueryWrapper<ProdSpu>().eq("brand_id", brandId).eq("cate_id", cateId));
        if(count>0){
            throw new CustomServiceException("该品牌下还有该分类的商品在售，禁止删除该分类");
        }
        prodCateBrandService.remove(new QueryWrapper<ProdCateBrand>().eq("brand_id",brandId).eq("cate_id",cateId));
    }

    @Transactional(rollbackFor = Exception.class)
    @Override
    public void addCate(Integer brandId, Integer cateId) {

        prodCateBrandService.save(new ProdCateBrand().setBrandId(brandId).setCateId(cateId));
    }
}
